package coder.interceptor;

import coder.common.BaseContext;
import coder.exception.BaseException;
import coder.exception.UnauthorizedException;
import coder.user.dto.UserDto;
import coder.user.entity.User;
import coder.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 使用slf4j日志框架记录日志信息
@Slf4j
// 标注为Spring的组件，自动装配到Spring应用上下文中
@Component
/**
 * 登录拦截器，用于拦截请求以验证用户登录状态
 * 实现了HandlerInterceptor接口，以使用Spring MVC的拦截器功能
 */
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 在请求处理之前进行调用，用于验证用户是否已登录
     *
     * @param request  HttpServletRequest对象，用于获取请求信息
     * @param response HttpServletResponse对象，用于设置响应信息
     * @param handler  请求处理之前的处理器
     * @return boolean 表示是否继续执行其他拦截器和处理器方法
     * @throws Exception 抛出基础异常类，用于处理用户未登录或登录信息失效的情况
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求头中获取token
        log.info("用户请求地址：{}", request.getRequestURI());
        String token = request.getHeader("Authorization");
        String url = request.getRequestURI();
        // 访问图片资源礼路径直接不拦截
        if(url.contains("images") || url.contains("error")) {
            return true;
        }
        // 如果token为空，抛出异常，表示用户未登录
        if(token == null) {
            throw new UnauthorizedException("用户未登录");
        }
        // 尝试解析JWT token，获取用户信息
        try {
            Claims user = JwtUtils.parseJwt(token);
            // 记录日志信息，表明用户已登录，并显示用户ID
            log.info("用户已登录，用户id为：{}", user.get("id"));
            BaseContext.setCurrentId(user.get("id").toString());
        } catch (Exception e) {
            // 如果解析token失败，抛出异常，表示登录信息已失效
            throw new UnauthorizedException("登录信息已失效");
        }
        // 返回true，表示继续执行其他拦截器和处理器方法
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
}

